package cn.calm.commons.service.defaultimpl;

import java.util.List;

import org.apache.log4j.Logger;

import cn.calm.commons.dao.IBaseDao;
import cn.calm.commons.dao.transaction.Transaction;
import cn.calm.commons.entity.BaseEntity;
import cn.calm.commons.entity.LogicallyDelete;
import cn.calm.commons.entity.PageMode;
import cn.calm.commons.exception.DeskException;
import cn.calm.commons.service.IBaseService;

public class DefaultServiceImpl<T extends BaseEntity> implements
		IBaseService<T> {
	protected IBaseDao baseDao;
	static final Logger logger = Logger.getLogger(DefaultServiceImpl.class);

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#list(cn.desk.commons.entity.BaseEntity
	 * )
	 */
	@Override
	public List<T> list(T t) {
		logger.debug("list start");
		try {
			return baseDao.list(t.getClass(),
					new DefaultQueryConditionBuilder<T>(t));
		} finally {
			logger.debug("list end");
		}
	}

	public IBaseDao getBaseDao() {
		return baseDao;
	}

	public void setBaseDao(IBaseDao baseDao) {
		this.baseDao = baseDao;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#add(cn.desk.commons.entity.BaseEntity
	 * )
	 */
	@Override
	public void add(T t) {
		logger.debug("add start");
		if (t.getId() != null) {
			T temp = baseDao.load(t.getClass(), t.getId());
			if (temp != null) {
				throw new DeskException("EM0001", t);
			}
		}
		baseDao.insert(t);
		logger.debug("add end");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#update(cn.desk.commons.entity.BaseEntity
	 * )
	 */
	@Override
	@Transaction
	public void update(T t) {
		logger.debug("update start");
		verify(t);
		baseDao.modify(t);
		logger.debug("update end");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#load(cn.desk.commons.entity.BaseEntity
	 * )
	 */
	@Override
	public T load(T t) {
		logger.debug("load start");
		try {
			T temp = verify(t);
			return temp;
		} finally {
			logger.debug("load end");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#delete(cn.desk.commons.entity.BaseEntity
	 * )
	 */
	@Override
	public void delete(T t) {
		logger.debug("delete start");
		T temp = verify(t);
		if (t instanceof LogicallyDelete) {
			LogicallyDelete ld = (LogicallyDelete) temp;
			ld.setDeleteClass(LogicallyDelete.DELETECLASS_DELETED);
			baseDao.modify(temp);
		} else {
			baseDao.delete(temp);
		}
		logger.debug("delete end");
	}

	// /*
	// * (non-Javadoc)
	// *
	// * @see
	// *
	// cn.desk.commons.service.IBaseService#update(cn.desk.commons.entity.BaseEntity
	// * )
	// */
	// @Override
	// public void merge(T t) {
	// logger.debug("update start");
	// verify(t);
	// baseDao(t);
	// logger.debug("update end");
	// }

	private T verify(T t) {
		T temp = baseDao.load(t.getClass(), t.getId());
		if (temp == null) {
			throw new DeskException("EM0002", t);
		}
		return temp;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#listPage(cn.desk.commons.entity.
	 * PageMode, cn.desk.commons.entity.BaseEntity)
	 */
	@Override
	public PageMode listPage(PageMode page, T t) {
		logger.debug("listPage start");
		try {

			return listPage(page, t, null);
		} finally {
			logger.debug("listPage end");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#listPage(cn.desk.commons.entity.
	 * PageMode, cn.desk.commons.entity.BaseEntity)
	 */
	@Override
	public PageMode listPage(PageMode page, final T t, final String asc) {
		logger.debug("listPage start");
		if (t instanceof LogicallyDelete) {
			((LogicallyDelete) t)
					.setDeleteClass(LogicallyDelete.DELETECLASS_NORMAL);
		}
		try {
			return baseDao.listPage(page, t.getClass(),
					new DefaultQueryConditionBuilder<T>(t, asc));
		} finally {
			logger.debug("listPage end");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.desk.commons.service.IBaseService#listInByProperty(java.lang.Class,
	 * java.lang.String, java.lang.String[])
	 */
	public List<T> listInByProperty(final Class<T> clazz,
			final String property, final String[] dependencies) {
		logger.debug("listInByProperty start");
		try {
			return baseDao.list(clazz, new PropertyInQueryConditionBuilder<T>(
					property, dependencies));
		} finally {
			logger.debug("listInByProperty end");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.desk.commons.service.IBaseService#listByProperty(java.lang.Class,
	 * java.lang.String, java.lang.Object)
	 */
	public List<T> listByProperty(final Class<? extends BaseEntity> clazz,
			final String property, Object value) {
		logger.debug("listByProperty start");
		try {
			return baseDao.list(clazz, new EqualQueryConditionBuilder<T>(
					property, value));
		} finally {
			logger.debug("listByProperty end");
		}
	}

	// /*
	// * (non-Javadoc)
	// *
	// * @see cn.desk.commons.service.IBaseService#getMax(java.lang.Class,
	// * java.lang.String)
	// */
	// @Override
	// public String getMax(Class<?> clazz, String property) {
	// logger.debug("getMax start");
	// try {
	// logger.info("Class:" + clazz + ",property:" + property);
	// return baseDao.getMax(clazz, property);
	// } finally {
	// logger.debug("getMax end");
	// }
	// }

	// /*
	// * (non-Javadoc)
	// *
	// * @see cn.desk.commons.service.IBaseService#getMax(java.lang.Class,
	// * java.lang.String)
	// */
	// @SuppressWarnings("unchecked")
	// @Override
	// @Deprecated
	// public Integer getNextId(Class<?> clazz) {
	// logger.debug("getMax start");
	// try {
	// logger.info("Class:" + clazz);
	// Sequence sequence = (Sequence) baseDao.load(Sequence.class,
	// clazz.getName());
	// if (sequence == null) {
	// sequence = new Sequence();
	// sequence.setId(clazz.getName());
	// sequence.setNext(0);
	// baseDao.insert((T) sequence);
	// return 0;
	// } else {
	// sequence.setNext(sequence.getNext() + 1);
	// baseDao.modify((T) sequence);
	// }
	// return sequence.getNext();
	// } finally {
	// logger.debug("getMax end");
	// }
	// }
}
